#pragma once

#include <brpc/server.h>
#include <butil/logging.h>

#include "asr.hpp"
#include "etcd.hpp"
#include "logger.hpp"
#include "speech.pb.h"

namespace xu
{
    class SpeechServicelmpl :public xu::SpeechService
    {
    public:
        SpeechServicelmpl(ASRClient::ptr asr_client)
        :_asr_client(asr_client)
        {}
        ~SpeechServicelmpl(){}

        virtual void SpeechRecognition(::google::protobuf::RpcController* controller,
                       const ::xu::SpeechRecognitionReq* request,
                       ::xu::SpeechRecognitionRsp* response,
                       ::google::protobuf::Closure* done)  override
        {
            brpc::ClosureGuard clo(done);
            //1.获取语音文件内容
            std::string speech_content = request->speech_content();
            //2.解析语音内容
            std::string err_msg;
            std::string res = _asr_client->Recognize(speech_content,err_msg);
            //3.组织响应
            if(res.empty())
            {
                LOG_ERROR("处理语音失败");
                response->set_request_id(request->request_id());
                response->set_success(false);
                response->set_errmsg(err_msg);
                response->set_recognition_result(res);
                return;
            }
            response->set_request_id(request->request_id());
            response->set_success(true);
            response->set_recognition_result(res);
            LOG_INFO("处理语音成功");
        }
    private:
        ASRClient::ptr _asr_client;
    };

    class SeepchServer
    {
    public:
        using ptr = std::shared_ptr<SeepchServer>;
        SeepchServer(xu::Registration::ptr reg,ASRClient::ptr asr_client,
            std::shared_ptr<brpc::Server> server)
            :_reg(reg),
            _asr_client(asr_client),
            _server(server)
        {}
        ~SeepchServer(){}
        void Start()
        {
            _server->RunUntilAskedToQuit();
        }
    private:
        xu::Registration::ptr _reg;
        ASRClient::ptr _asr_client;
        std::shared_ptr<brpc::Server> _server;
    };

    class SpeechServerBuilder
    {
    public:
        SpeechServerBuilder(){}
        ~SpeechServerBuilder(){}

        void SetRcpReg(const std::string &host,const std::string &service_name,
            const std::string &access_host)
        {
            _reg = std::make_shared<Registration>(host);
            _reg->AddKV(service_name,access_host);
        }
        void SetRpcAsrClient(const std::string &app_id, const std::string &api_key,
             const std::string &secret_key)
        {
            _asr_client = std::make_shared<ASRClient>(app_id,api_key,secret_key);        
        }
        void SetRpcServer(uint16_t port, int32_t timeout, uint8_t num_threads)
        {
            if(!_asr_client)
            {
                LOG_ERROR("AsrClient未初始化");
                return;
            }

            _server = std::make_shared<brpc::Server>();

            SpeechServicelmpl *specchservice = new  SpeechServicelmpl(_asr_client);
            _server->AddService(specchservice,brpc::ServiceOwnership::SERVER_OWNS_SERVICE);

            brpc::ServerOptions options;
            options.idle_timeout_sec = timeout;
            options.num_threads = num_threads;

            _server->Start(port, &options);
        }
        SeepchServer::ptr Build()
        {
            if(!_asr_client)
            {
                LOG_ERROR("AsrClient未初始化");
                return SeepchServer::ptr();
            }

            if(!_reg)
            {
                LOG_ERROR("RcpReg未初始化");
                return SeepchServer::ptr();
            }

            if(!_server)
            {
                LOG_ERROR("RpcServer未初始化");
                return SeepchServer::ptr();
            }

            auto res = std::make_shared<SeepchServer>(_reg, _asr_client,_server);
            return res;
        }

    private:
        xu::Registration::ptr _reg;
        ASRClient::ptr _asr_client;
        std::shared_ptr<brpc::Server> _server;
    };
}
